/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package de.tor.tribes.types;

import de.tor.tribes.reportserver.PersistenceImpl;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;

/**
 *
 * @author Torridity
 */
@Entity
@Table(name = "ReportUsers")
public class ZebraUser implements Serializable {

    @Id
    @GeneratedValue
    private Long userId;
    private String name;
    private String passwordHash;
    private String email;
    @OneToMany(mappedBy = "reportUser", cascade = CascadeType.ALL)
    private Set<ZebraGroupMembership> memberships;

    public ZebraUser() {
        memberships = new HashSet<ZebraGroupMembership>();
    }

    public void setId(Long id) {
        this.userId = id;
    }

    public Long getId() {
        return userId;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getEmail() {
        return email;
    }

    public void setPlainPassword(String pPassword) {
        setPasswordHash(DigestUtils.md5Hex(DigestUtils.getMd5Digest().digest(pPassword.getBytes())));
    }

    public void setPasswordHash(String passwordHash) {
        this.passwordHash = passwordHash;
    }

    public String getPasswordHash() {
        return passwordHash;
    }

    public boolean isAdmin(final ZebraGroup pGroup) {
        ZebraGroupMembership m = findMembership(pGroup);
        if (m != null) {
            return m.getRole().equals(ZebraRole.ADMIN);
        }
        return false;
    }

    public ZebraRole getRole(final ZebraGroup pGroup) {
        ZebraGroupMembership m = findMembership(pGroup);
        if (m != null) {
            return m.getRole();
        }
        return null;
    }

    public boolean canInvite(final ZebraGroup pGroup) {
        ZebraGroupMembership m = findMembership(pGroup);
        if (m != null) {
            return !m.getRole().equals(ZebraRole.MEMBER);
        }
        return false;
    }

    public ZebraGroupMembership[] getMemberships() {
        return getMemberships(false);
    }

    public ZebraGroupMembership[] getMemberships(boolean pOrder) {
        ZebraGroupMembership[] result = memberships.toArray(new ZebraGroupMembership[memberships.size()]);
        if (pOrder) {
            Arrays.sort(result, ZebraGroupMembership.MEMBERSHIP_GROUP_COMPARATOR);
        }
        return result;
    }

    public void leaveGroup(final ZebraGroup pGroup, PersistenceImpl pPersistence) {
        ZebraGroupMembership m = findMembership(pGroup);
        if (m != null) {
            memberships.remove(m);
            pGroup.removeUser(this, pPersistence);
            pPersistence.persistUser(this);
            pPersistence.removeMembership(m);
        }
    }

    public void acceptGroupInvitation(final ZebraGroup pGroup, PersistenceImpl pPersistence) {
        ZebraGroupMembership m = findMembership(pGroup);
        if (m != null) {
            m.setAccepted(true);
            pPersistence.persist(m);
            pPersistence.reloadUserGroup(pGroup);
            pPersistence.reloadUser(this);
        }
    }

    protected void removeMembership(ZebraGroupMembership pMembership) {
        memberships.remove(pMembership);
    }

    private ZebraGroupMembership findMembership(final ZebraGroup pGroup) {
        return (ZebraGroupMembership) CollectionUtils.find(memberships, new Predicate() {
            public boolean evaluate(Object o) {
                ZebraGroupMembership m = (ZebraGroupMembership) o;
                return m.getUserGroup().equals(pGroup);
            }
        });
    }
}
